import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import RcTable, { INTERNAL_COL_DEFINE } from 'rc-table';
import classNames from 'classnames';
import shallowEqual from 'shallowequal';
import { Button, Icon } from 'antd';
import Spin from '@/components/Spin';
import SelectionBox from '@/components/SelectionBox';
import Pagination from '../Pagination';
import createStore from 'antd/es/table/createStore';
import createBodyRow from 'antd/es/table/createBodyRow';
import SelectionCheckboxAll from './SelectionCheckboxAll';
import { flatArray, treeMap, flatFilter, normalizeColumns } from 'antd/es/table/util';

function noop() {}
function stopPropagation(e) {
  e.stopPropagation();
  if (e.nativeEvent.stopImmediatePropagation) {
    e.nativeEvent.stopImmediatePropagation();
  }
}
function getRowSelection(props) {
  return props.rowSelection || {};
}
const defaultPagination = {
  onChange: noop,
  onShowSizeChange: noop,
};
const emptyObject = {};

export default class Table extends React.Component {
  constructor(props) {
    super(props);
    this.columns = props.columns || normalizeColumns(props.children);

    this.createComponents(props.components);

    this.state = {
      ...this.getDefaultSortOrder(this.columns),
      pagination: this.getDefaultPagination(props),
    };
    this.CheckboxPropsCache = {};

    this.store = createStore({
      selectedRowKeys: getRowSelection(props).selectedRowKeys || [],
      selectionDirty: false,
    });
  }
  static propTypes = {
    columns: PropTypes.array,
    data: PropTypes.array,
  };
  static defaultProps = {
    rowKey: 'id',
    useFixedHeader: true,
    data: [],
    loading: false,
    scroll: {
      x: true,
      y: true,
    },
    sortDirections: ['asc', 'desc'],
  };
  hasPagination(props) {
    return (props || this.props).pagination !== false;
  }
  getSortOrderColumns(columns) {
    return flatFilter(columns || this.columns || [], column => 'sortOrder' in column);
  }
  getLocalData(state) {
    // const currentState = state || this.state
    const { data } = this.props;
    let _data = data || [];
    _data = _data.slice(0);
    return _data;
  }
  getDefaultPagination(props) {
    const pagination = typeof props.pagination === 'object' ? props.pagination : {};
    let pageNumber;
    if ('pageNumber' in pagination) {
      pageNumber = pagination.pageNumber;
    } else if ('defaultCurrent' in pagination) {
      pageNumber = pagination.defaultCurrent;
    }
    let pageSize;
    if ('pageSize' in pagination) {
      pageSize = pagination.pageSize;
    } else if ('defaultPageSize' in pagination) {
      pageSize = pagination.defaultPageSize;
    }
    return this.hasPagination(props)
      ? {
          ...defaultPagination,
          ...pagination,
          pageNumber: pageNumber || 1,
          pageSize: pageSize || 20,
        }
      : {};
  }
  getDefaultSelection() {
    const rowSelection = getRowSelection(this.props);
    if (!rowSelection.getCheckboxProps) {
      return [];
    }
    return this.getFlatData()
      .filter((item, rowIndex) => this.getCheckboxPropsByItem(item, rowIndex).defaultChecked)
      .map((record, rowIndex) => this.getRecordKey(record, rowIndex));
  }
  componentWillReceiveProps(nextProps) {
    this.columns = nextProps.columns || normalizeColumns(nextProps.children);
    if ('pagination' in nextProps || 'pagination' in this.props) {
      this.setState(previousState => {
        const newPagination = {
          ...defaultPagination,
          ...previousState.pagination,
          ...nextProps.pagination,
        };
        newPagination.pageNumber = newPagination.pageNumber || 1;
        newPagination.pageSize = newPagination.pageSize || 10;
        return {
          pagination: nextProps.pagination !== false ? newPagination : emptyObject,
        };
      });
    }
    if (nextProps.rowSelection && 'selectedRowKeys' in nextProps.rowSelection) {
      this.store.setState({
        selectedRowKeys: nextProps.rowSelection.selectedRowKeys || [],
      });
    } else if (this.props.rowSelection && !nextProps.rowSelection) {
      this.store.setState({
        selectedRowKeys: [],
      });
    }
    if ('data' in nextProps && nextProps.data !== this.props.data) {
      this.store.setState({
        selectionDirty: false,
      });
    }

    this.CheckboxPropsCache = {};

    if (this.getSortOrderColumns(this.columns).length > 0) {
      const sortState = this.getSortStateFromColumns(this.columns);
      if (
        sortState.sortColumn !== this.state.sortColumn ||
        sortState.sortOrder !== this.state.sortOrder
      ) {
        this.setState(sortState);
      }
    }

    this.createComponents(nextProps.components, this.props.components);
  }
  onRow = (prefixCls, record, index) => {
    const { rowSelection } = this.props;
    const rowKey = this.getRecordKey(record, index);
    const {
      onRow = (item, i) => {
        return {
          onClick: event => {
            if (rowSelection && !this.getCheckboxPropsByItem(item, i).disabled) {
              const state = this.store.getState();
              const defaultSelection = state.selectionDirty ? [] : this.getDefaultSelection();
              let selectedRowKeys = state.selectedRowKeys.concat(defaultSelection);

              let checked;
              if (selectedRowKeys.indexOf(rowKey) === -1) {
                // selectedRowKeys.push(rowKey);
                selectedRowKeys = [rowKey];
                this.setState({
                  pivot: i,
                });
                checked = true;
              } else {
                // selectedRowKeys = selectedRowKeys.filter((i) => rowKey !== i);
                if (selectedRowKeys.length > 1) {
                  selectedRowKeys = [rowKey];
                  checked = true;
                } else {
                  selectedRowKeys = [];
                  checked = false;
                }
              }

              this.store.setState({
                selectionDirty: true,
              });
              this.setSelectedRowKeys(selectedRowKeys, {
                selectWay: 'onSelect',
                record: item,
                checked,
                changeRowKeys: void 0,
                nativeEvent: event.nativeEvent,
              });
            }
          },
        };
      },
    } = this.props;
    const custom = onRow(record, index);
    return {
      ...custom,
      prefixCls,
      store: this.store,
      rowKey: rowKey,
    };
  };
  setSelectedRowKeys(selectedRowKeys, selectionInfo) {
    const { selectWay, record, checked, changeRowKeys, nativeEvent } = selectionInfo;
    const rowSelection = getRowSelection(this.props);
    if (rowSelection && !('selectedRowKeys' in rowSelection)) {
      this.store.setState({
        selectedRowKeys,
      });
    }
    const data = this.getFlatData();
    if (!rowSelection.onChange && !rowSelection[selectWay]) {
      return;
    }
    const selectedRows = data.filter(
      (row, i) => selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0,
    );
    if (rowSelection.onChange) {
      rowSelection.onChange(selectedRowKeys, selectedRows);
    }
    if (selectWay === 'onSelect' && rowSelection.onSelect) {
      rowSelection.onSelect(record, checked, selectedRows, nativeEvent);
    } else if (selectWay === 'onSelectMultiple' && rowSelection.onSelectMultiple) {
      const changeRows = data.filter(
        (row, i) => changeRowKeys.indexOf(this.getRecordKey(row, i)) >= 0,
      );
      rowSelection.onSelectMultiple(checked, selectedRows, changeRows);
    } else if (selectWay === 'onSelectAll' && rowSelection.onSelectAll) {
      const changeRows = data.filter(
        (row, i) => changeRowKeys.indexOf(this.getRecordKey(row, i)) >= 0,
      );
      rowSelection.onSelectAll(checked, selectedRows, changeRows);
    } else if (selectWay === 'onSelectInvert' && rowSelection.onSelectInvert) {
      rowSelection.onSelectInvert(selectedRowKeys);
    }
  }
  renderPagination(prefixCls) {
    if (!this.hasPagination()) {
      return null;
    }
    const { pagination } = this.state;
    const total = pagination.total || this.getLocalData().length;
    const pageCls = `${prefixCls}-footer`;
    return (
      <div className={pageCls}>
        <Pagination
          showTotal={(total, range, pageNumber, pageSize, pages) =>
            `共${pages}页，每页${pageSize}条，当前第${pageNumber}/${pages}页，共${total}条`
          }
          {...pagination}
          onChange={this.handlePageChange}
          total={total}
          pageNumber={this.getMaxCurrent(total)}
        />
      </div>
    );
  }
  getColumnKey(column, index) {
    return column.key || column.dataIndex || index;
  }
  getMaxCurrent(total) {
    const {
      pagination: { pageNumber, pageSize },
    } = this.state;
    if ((pageNumber - 1) * pageSize >= total) {
      return Math.floor((total - 1) / pageSize) + 1;
    }
    return pageNumber;
  }
  prepareParamsArguments(state) {
    const pagination = { ...state.pagination };
    delete pagination.onChange;
    delete pagination.onShowSizeChange;
    const sorter = {};
    if (state.sortColumn && state.sortOrder) {
      sorter.column = state.sortColumn;
      sorter.order = state.sortOrder;
      sorter.field = state.sortColumn.dataIndex;
      sorter.columnKey = this.getColumnKey(state.sortColumn);
    }

    const extra = {
      data: this.getLocalData(state),
    };

    return [pagination, sorter, extra];
  }
  getCurrentPageData() {
    let data = this.getLocalData();
    let pageNumber;
    let pageSize;
    const state = this.state;
    if (!this.hasPagination()) {
      pageSize = Number.MAX_VALUE;
      pageNumber = 1;
    } else {
      pageSize = state.pagination.pageSize;
      pageNumber = this.getMaxCurrent(state.pagination.total || data.length);
    }

    if (data.length > pageSize || pageSize === Number.MAX_VALUE) {
      data = data.filter((_, i) => {
        return i >= (pageNumber - 1) * pageSize && i < pageNumber * pageSize;
      });
    }
    return data;
  }
  getFlatData() {
    const { childrenColumnName } = this.props;
    return flatArray(this.getLocalData(null, false), childrenColumnName);
  }
  getFlatCurrentPageData() {
    const { childrenColumnName } = this.props;
    return flatArray(this.getCurrentPageData(), childrenColumnName);
  }
  getDefaultSortOrder(columns) {
    const definedSortState = this.getSortStateFromColumns(columns);

    const defaultSortedColumn = flatFilter(
      columns || [],
      column => column.defaultSortOrder != null,
    )[0];

    if (defaultSortedColumn && !definedSortState.sortColumn) {
      return {
        sortColumn: defaultSortedColumn,
        sortOrder: defaultSortedColumn.defaultSortOrder,
      };
    }
    return definedSortState;
  }
  getSortStateFromColumns(columns) {
    const sortedColumn = this.getSortOrderColumns(columns).filter(col => col.sortOrder)[0];

    if (sortedColumn) {
      return {
        sortColumn: sortedColumn,
        sortOrder: sortedColumn.sortOrder,
      };
    }

    return {
      sortColumn: null,
      sortOrder: null,
    };
  }
  getSorterFn(state) {
    const { sortOrder, sortColumn } = state || this.state;
    if (!sortOrder || !sortColumn || typeof sortColumn.sorter !== 'function') {
      return;
    }

    return (a, b) => {
      const result = sortColumn.sorter(a, b, sortOrder);
      if (result !== 0) {
        return sortOrder === 'desc' ? -result : result;
      }
      return 0;
    };
  }
  isSameColumn(a, b) {
    if (a && b && a.key && a.key === b.key) {
      return true;
    }
    return (
      a === b ||
      shallowEqual(a, b, (value, other) => {
        if (typeof value === 'function' && typeof other === 'function') {
          return value === other || value.toString() === other.toString();
        }
      })
    );
  }
  toggleSortOrder(column) {
    if (!column.sorter) {
      return;
    }
    const sortDirections = column.sortDirections || this.props.sortDirections;
    const { sortOrder, sortColumn } = this.state;
    let newSortOrder;
    if (this.isSameColumn(sortColumn, column) && sortOrder !== undefined) {
      const methodIndex = sortDirections.indexOf(sortOrder) + 1;
      newSortOrder =
        methodIndex === sortDirections.length ? undefined : sortDirections[methodIndex];
    } else {
      newSortOrder = sortDirections[0];
    }

    const newState = {
      sortOrder: newSortOrder,
      sortColumn: newSortOrder ? column : null,
    };

    if (this.getSortOrderColumns().length === 0) {
      this.setState(newState);
    }

    const { onChange } = this.props;
    if (onChange) {
      onChange.apply(
        null,
        this.prepareParamsArguments({
          ...this.state,
          ...newState,
        }),
      );
    }
  }
  handleSelect = (record, rowIndex, e) => {
    const checked = e.target.checked;
    const nativeEvent = e.nativeEvent;
    const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection();
    let selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection);
    const key = this.getRecordKey(record, rowIndex);
    const { pivot } = this.state;
    const rows = this.getFlatCurrentPageData();
    let realIndex = rowIndex;
    if (this.props.expandedRowRender) {
      realIndex = rows.findIndex(row => this.getRecordKey(row, rowIndex) === key);
    }

    if (nativeEvent.shiftKey && pivot !== undefined && realIndex !== pivot) {
      const changeRowKeys = [];
      const direction = Math.sign(pivot - realIndex);
      const dist = Math.abs(pivot - realIndex);
      let step = 0;
      while (step <= dist) {
        const i = realIndex + step * direction;
        step += 1;
        const row = rows[i];
        const rowKey = this.getRecordKey(row, i);
        const checkboxProps = this.getCheckboxPropsByItem(row, i);
        if (!checkboxProps.disabled) {
          if (selectedRowKeys.includes(rowKey)) {
            if (!checked) {
              selectedRowKeys = selectedRowKeys.filter(j => rowKey !== j);
              changeRowKeys.push(rowKey);
            }
          } else if (checked) {
            selectedRowKeys.push(rowKey);
            changeRowKeys.push(rowKey);
          }
        }
      }

      this.setState({
        pivot: realIndex,
      });
      this.store.setState({
        selectionDirty: true,
      });
      this.setSelectedRowKeys(selectedRowKeys, {
        selectWay: 'onSelectMultiple',
        record,
        checked,
        changeRowKeys,
        nativeEvent,
      });
    } else {
      if (checked) {
        selectedRowKeys.push(this.getRecordKey(record, realIndex));
      } else {
        selectedRowKeys = selectedRowKeys.filter(i => key !== i);
      }

      this.setState({
        pivot: realIndex,
      });
      this.store.setState({
        selectionDirty: true,
      });
      this.setSelectedRowKeys(selectedRowKeys, {
        selectWay: 'onSelect',
        record,
        checked,
        changeRowKeys: void 0,
        nativeEvent,
      });
    }
  };
  handleRadioSelect = (record, rowIndex, e) => {
    const checked = e.target.checked;
    const nativeEvent = e.nativeEvent;
    const key = this.getRecordKey(record, rowIndex);
    const selectedRowKeys = [key];
    this.store.setState({
      selectionDirty: true,
    });
    this.setSelectedRowKeys(selectedRowKeys, {
      selectWay: 'onSelect',
      record,
      checked,
      changeRowKeys: void 0,
      nativeEvent,
    });
  };
  handleSelectRow = (selectionKey, index, onSelectFunc) => {
    const data = this.getFlatCurrentPageData();
    const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection();
    const selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection);
    const changeableRowKeys = data
      .filter((item, i) => !this.getCheckboxPropsByItem(item, i).disabled)
      .map((item, i) => this.getRecordKey(item, i));

    const changeRowKeys = [];
    let selectWay = 'onSelectAll';
    let checked;
    switch (selectionKey) {
      case 'all':
        changeableRowKeys.forEach(key => {
          if (selectedRowKeys.indexOf(key) < 0) {
            selectedRowKeys.push(key);
            changeRowKeys.push(key);
          }
        });
        selectWay = 'onSelectAll';
        checked = true;
        break;
      case 'removeAll':
        changeableRowKeys.forEach(key => {
          if (selectedRowKeys.indexOf(key) >= 0) {
            selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1);
            changeRowKeys.push(key);
          }
        });
        selectWay = 'onSelectAll';
        checked = false;
        break;
      case 'invert':
        changeableRowKeys.forEach(key => {
          if (selectedRowKeys.indexOf(key) < 0) {
            selectedRowKeys.push(key);
          } else {
            selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1);
          }
          changeRowKeys.push(key);
          selectWay = 'onSelectInvert';
        });
        break;
      default:
        break;
    }

    this.store.setState({
      selectionDirty: true,
    });
    const { rowSelection } = this.props;
    let customSelectionStartIndex = 2;
    if (rowSelection && rowSelection.hideDefaultSelections) {
      customSelectionStartIndex = 0;
    }
    if (index >= customSelectionStartIndex && typeof onSelectFunc === 'function') {
      return onSelectFunc(changeableRowKeys);
    }
    this.setSelectedRowKeys(selectedRowKeys, {
      selectWay,
      checked,
      changeRowKeys,
    });
  };
  handlePageChange = (pageNumber, ...otherArguments) => {
    const props = this.props;
    const pagination = { ...this.state.pagination };
    if (pageNumber) {
      pagination.pageNumber = pageNumber;
    } else {
      pagination.pageNumber = pagination.pageNumber || 1;
    }
    pagination.onChange(pagination.pageNumber, ...otherArguments);

    const newState = {
      pagination,
    };
    if (
      props.pagination &&
      typeof props.pagination === 'object' &&
      'pageNumber' in props.pagination
    ) {
      newState.pagination = {
        ...pagination,
        pageNumber: this.state.pagination.pageNumber,
      };
    }
    this.setState(newState);

    this.store.setState({
      selectionDirty: false,
    });

    const { onChange } = this.props;
    if (onChange) {
      onChange.apply(
        null,
        this.prepareParamsArguments({
          ...this.state,
          selectionDirty: false,
          pagination,
        }),
      );
    }
  };
  getRecordKey = (record, index) => {
    const { rowKey } = this.props;
    const recordKey = typeof rowKey === 'function' ? rowKey(record, index) : record[rowKey];

    return recordKey === undefined ? index : recordKey;
  };
  getPopupContainer = () => {
    return ReactDOM.findDOMNode(this);
  };
  generatePopupContainerFunc = () => {
    const { scroll } = this.props;

    return scroll ? this.getPopupContainer : undefined;
  };
  getCheckboxPropsByItem = (item, index) => {
    const rowSelection = getRowSelection(this.props);
    if (!rowSelection.getCheckboxProps) {
      return {};
    }
    const key = this.getRecordKey(item, index);
    if (!this.CheckboxPropsCache[key]) {
      this.CheckboxPropsCache[key] = rowSelection.getCheckboxProps(item);
    }
    return this.CheckboxPropsCache[key];
  };
  renderSelectionBox = type => {
    return (_, record, index) => {
      const rowKey = this.getRecordKey(record, index);
      const props = this.getCheckboxPropsByItem(record, index);
      const handleChange = e => {
        type === 'radio'
          ? this.handleRadioSelect(record, index, e)
          : this.handleSelect(record, index, e);
      };

      return (
        <span onClick={stopPropagation}>
          <SelectionBox
            type={type}
            store={this.store}
            rowIndex={rowKey}
            onChange={handleChange}
            defaultSelection={this.getDefaultSelection()}
            {...props}
            prefixCls="x-selectable"
          />
        </span>
      );
    };
  };
  renderRowSelection(prefixCls) {
    const { rowSelection } = this.props;
    const columns = this.columns.concat();
    if (rowSelection) {
      const data = this.getFlatCurrentPageData().filter((item, index) => {
        if (rowSelection.getCheckboxProps) {
          return !this.getCheckboxPropsByItem(item, index).disabled;
        }
        return true;
      });
      const selectionColumnClass = classNames(`${prefixCls}-selection-column`, {
        [`${prefixCls}-selection-column-custom`]: rowSelection.selections,
      });
      const selectionColumn = {
        key: 'selection-column',
        render: this.renderSelectionBox(rowSelection.type),
        className: selectionColumnClass,
        fixed: rowSelection.fixed,
        width: rowSelection.columnWidth,
        title: rowSelection.columnTitle,
        [INTERNAL_COL_DEFINE]: {
          className: `${prefixCls}-selection-col`,
        },
      };
      if (rowSelection.type !== 'radio') {
        const checkboxAllDisabled = data.every(
          (item, index) => this.getCheckboxPropsByItem(item, index).disabled,
        );
        selectionColumn.title = selectionColumn.title || (
          <SelectionCheckboxAll
            store={this.store}
            data={data}
            locale={{
              selectAll: '全选当页',
              selectInvert: '反选当页',
            }}
            getCheckboxPropsByItem={this.getCheckboxPropsByItem}
            getRecordKey={this.getRecordKey}
            disabled={checkboxAllDisabled}
            prefixCls={prefixCls}
            onSelect={this.handleSelectRow}
            selections={rowSelection.selections}
            hideDefaultSelections={rowSelection.hideDefaultSelections}
            getPopupContainer={this.generatePopupContainerFunc()}
          />
        );
      }
      if ('fixed' in rowSelection) {
        selectionColumn.fixed = rowSelection.fixed;
      } else if (columns.some(column => column.fixed === 'left' || column.fixed === true)) {
        selectionColumn.fixed = 'left';
      }
      if (columns[0] && columns[0].key === 'selection-column') {
        columns[0] = selectionColumn;
      } else {
        columns.unshift(selectionColumn);
      }
    }
    return columns;
  }
  createComponents(components = {}, prevComponents) {
    const bodyRow = components && components.body && components.body.row;
    const preBodyRow = prevComponents && prevComponents.body && prevComponents.body.row;
    if (!this.row || bodyRow !== preBodyRow) {
      this.row = createBodyRow(bodyRow);
    }
    this.components = {
      ...components,
      body: {
        ...components.body,
        row: this.row,
      },
    };
  }
  renderColumnTitle(title) {
    const { sortOrder } = this.state;
    if (title instanceof Function) {
      return title({
        sortOrder,
      });
    }
    return title;
  }
  isSortColumn(column) {
    const { sortColumn } = this.state;
    if (!column || !sortColumn) {
      return false;
    }
    return this.getColumnKey(sortColumn) === this.getColumnKey(column);
  }
  renderColumnsDropdown(prefixCls, columns) {
    const { sortOrder } = this.state;
    return treeMap(columns, (column, i) => {
      // const key = this.getColumnKey(column, i)
      let sortButton;
      let onHeaderCell = column.onHeaderCell;
      const isSortColumn = this.isSortColumn(column);

      if (column.sorter) {
        const sortDirections = column.sortDirections || this.props.sortDirections;
        const isAscend = isSortColumn && sortOrder === 'asc';
        const isDescend = isSortColumn && sortOrder === 'desc';

        const ascend = sortDirections.indexOf('asc') !== -1 && (
          <Icon
            className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
            type="caret-up"
            theme="filled"
          />
        );
        const descend = sortDirections.indexOf('desc') !== -1 && (
          <Icon
            className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
            type="caret-down"
            theme="filled"
          />
        );
        sortButton = (
          <div
            title="排序"
            className={classNames(
              `${prefixCls}-column-sorter-inner`,
              ascend && descend && `${prefixCls}-column-sorter-inner-full`,
            )}
            key="sorter"
          >
            {ascend}
            {descend}
          </div>
        );
        onHeaderCell = col => {
          let colProps = {};
          if (column.onHeaderCell) {
            colProps = {
              ...column.onHeaderCell(col),
            };
          }
          const onHeaderCellClick = colProps.onClick;
          colProps.onClick = (...args) => {
            this.toggleSortOrder(column);
            if (onHeaderCellClick) {
              onHeaderCellClick(...args);
            }
          };
          return colProps;
        };
      }
      return {
        ...column,
        className: classNames(column.className, {
          [`${prefixCls}-column-has-actions`]: sortButton,
          [`${prefixCls}-column-has-sorters`]: sortButton,
          [`${prefixCls}-column-sort`]: isSortColumn && sortOrder,
        }),
        title: [
          <span key="title" className={`${prefixCls}-header-column`}>
            <div className={sortButton ? `${prefixCls}-column-sorters` : undefined}>
              <span className={`${prefixCls}-column-title`}>
                {this.renderColumnTitle(column.title)}
              </span>
              <span className={`${prefixCls}-column-sorter`}>{sortButton}</span>
            </div>
          </span>,
        ],
        onHeaderCell,
      };
    });
  }
  renderTable(prefixCls) {
    const { forceFit, ...props } = this.props;
    let data = this.getCurrentPageData();
    let columns = this.renderRowSelection(prefixCls);
    columns = this.renderColumnsDropdown(prefixCls, columns);
    columns = columns.map((column, i) => {
      const newColumn = { ...column };
      newColumn.key = this.getColumnKey(newColumn, i);
      return newColumn;
    });
    if (forceFit === false) {
      const forceColumn = {
        key: 'force-column',
      };
      columns.push(forceColumn);
    }
    return (
      <RcTable
        {...props}
        data={data}
        columns={columns}
        prefixCls={prefixCls}
        onRow={(record, index) => this.onRow(prefixCls, record, index)}
        components={this.components}
      />
    );
  }
  renderComponent(prefixCls) {
    let { showHeader, showReload, loading } = this.props;
    if (typeof loading === 'boolean') {
      loading = {
        spinning: loading,
      };
    }
    const table = this.renderTable(prefixCls);
    return (
      <Spin {...loading} wrapperClassName={`${prefixCls}-loading`}>
        {showHeader !== false && showReload !== false && (
          <Button
            type="link"
            className={`${prefixCls}-reload`}
            size="small"
            disabled={this.props.loading}
            icon="reload"
            onClick={this.props.onReload}
          ></Button>
        )}
        {table}
        {this.renderPagination(prefixCls)}
      </Spin>
    );
  }
  render() {
    const { prefixCls } = this.props;

    return <>{this.renderComponent(prefixCls)}</>;
  }
}
